package com.mls.guardian.remoting.netty;

import com.mls.guardian.common.RemoteCommandType;
import com.mls.guardian.protocol.RemoteBody;
import com.mls.guardian.protocol.RemoteCommand;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.*;
import java.util.ArrayList;
import java.util.Enumeration;

/**
 * Created by jl on 15/9/10.
 */
public class RemoteTools {
    private static final Logger log = LoggerFactory.getLogger(RemoteTools.class);
    /**
     * IP:PORT
     */
    public static SocketAddress string2SocketAddress(final String addr) {
        String[] s = addr.split(":");
        InetSocketAddress isa = new InetSocketAddress(s[0], Integer.valueOf(s[1]));
        return isa;
    }

    public static RemoteCommand getRequestRemoteCmd(int code,RemoteBody remoteBody){
        RemoteCommand remoteCommand = new RemoteCommand();
        remoteCommand.setCode(code);
        remoteCommand.setRemoteCommandType(RemoteCommandType.REQUEST);
        remoteCommand.setRemoteBody(remoteBody);

        return remoteCommand;
    }


    public static RemoteCommand getReponseRemoteCmd(int code,RemoteBody remoteBody){
        RemoteCommand remoteCommand = new RemoteCommand();
        remoteCommand.setCode(code);
        remoteCommand.setRemoteCommandType(RemoteCommandType.RESPONSE);
        remoteCommand.setRemoteBody(remoteBody);

        return remoteCommand;
    }

    public static String getRemoteAddr(Channel channel){
        if(channel == null){
            return "";
        }

        final SocketAddress remote = channel.remoteAddress();
        String addr = remote != null ? remote.toString() : "";

        if(addr.equals("")) {
            return addr;
        }

        addr = cutPort(addr);

        if (addr.length() > 0) {
            int index = addr.lastIndexOf("/");
            if (index >= 0) {
                addr = addr.substring(index + 1);
            }

            return addr;
        }

        return addr;
    }



    public static InetAddress getAddress() {
        try {
            for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) {
                NetworkInterface networkInterface = interfaces.nextElement();
                if (networkInterface.isLoopback() || networkInterface.isVirtual() || !networkInterface.isUp()) {
                    continue;
                }
                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                if (addresses.hasMoreElements()) {
                    return addresses.nextElement();
                }
            }
        } catch (SocketException e) {
            log.debug("Error when getting host ip address: <{}>.", e.getMessage());
        }
        return null;
    }
    public  static String cutPort(String addr){
        int index = addr.lastIndexOf(":");
        return addr.substring(0,index);
    }

    public static String exceptionSimpleDesc(final Throwable e) {
        StringBuffer sb = new StringBuffer();
        if (e != null) {
            sb.append(e.toString());

            StackTraceElement[] stackTrace = e.getStackTrace();
            if (stackTrace != null && stackTrace.length > 0) {
                StackTraceElement elment = stackTrace[0];
                sb.append(", ");
                sb.append(elment.toString());
            }
        }

        return sb.toString();
    }


    public static String parseChannelRemoteAddr(final Channel channel) {
        if (null == channel) {
            return "";
        }
        final SocketAddress remote = channel.remoteAddress();
        final String addr = remote != null ? remote.toString() : "";

        if (addr.length() > 0) {
            int index = addr.lastIndexOf("/");
            if (index >= 0) {
                return addr.substring(index + 1);
            }

            return addr;
        }

        return "";
    }

    public static void closeChannel(Channel channel) {
        final String addrRemote = parseChannelRemoteAddr(channel);
        channel.close().addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                log.info("closeChannel: close the connection to remote address[{}] result: {}", addrRemote,
                        future.isSuccess());
            }
        });
    }

    public static void main(String[] args) throws Exception {
    }

}
